package com.leesche.zcsp.node.pay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.leesche.zcsp.node.pay.service.RmPayService;
import com.leesche.zcsp.node.pay.wecha.data.Message;
import com.leesche.zcsp.node.utils.MD5Util;
import com.leesche.zcsp.node.utils.PayConfig;
import com.leesche.zcsp.node.web.model.ServOrder;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author reid
 * @Created 16/12/7
 */
@Service
public class RmPayServiceImpl implements RmPayService {

    private static final Logger LOGGER = Logger.getLogger(RmPayServiceImpl.class);

    @Override
    public Message<String> prePay(ServOrder order, String openid) {

        JSONObject params = new JSONObject();
        params.put("tradeType", PayConfig.RM_TRADETYPE);
        params.put("version", "1.0");
        params.put("channel", PayConfig.RM_WECHAT_PAY);
        params.put("mchId", PayConfig.RM_MCHID_TEST);
        params.put("body", "下订单");
        params.put("outTradeNo", order.getOutTradeNo());
        params.put("amount", "0.01");

        JSONObject extra = new JSONObject();
        extra.put("callbackUrl", PayConfig.RM_CALLBACK_URL);
        extra.put("notifyUrl", PayConfig.RM_NOTIFY_URL);
        extra.put("openId", PayConfig.RM_OPENID_TEST);
        params.put("extra", extra);

        JSONArray detailsArray = new JSONArray();
        JSONObject details = new JSONObject(true);
        details.put("amount", "0.01");
        details.put("innerOrderNo", order.getOutTradeNo());
        details.put("virAccNo", "0");
        detailsArray.add(details);
        params.put("details",detailsArray);

        /*JsonArray jsonArray = new JsonArray();
        JsonObject jsonObject = new JsonObject();

        jsonObject.addProperty("tradeType", PayConfig.RM_TRADETYPE);
        jsonObject.addProperty("version", "1.0");
        jsonObject.addProperty("channel", PayConfig.RM_WECHAT_PAY);
        jsonObject.addProperty("mchId", PayConfig.RM_MCHID_TEST);
        jsonObject.addProperty("body", "下订单");
        jsonObject.addProperty("outTradeNo", order.getOutTradeNo());
        jsonObject.addProperty("amount", 0.01);

        JsonObject extra = new JsonObject();
        extra.addProperty("callbackUrl", PayConfig.RM_CALLBACK_URL);
        extra.addProperty("notifyUrl", PayConfig.RM_NOTIFY_URL);
        extra.addProperty("openId", PayConfig.RM_OPENID_TEST);
        LOGGER.info("extra=" + extra.toString());

        JsonObject details = new JsonObject();
        details.addProperty("amount", 0.01);
        details.addProperty("innerOrderNo", order.getOutTradeNo());
        details.addProperty("virAccNo", "0");
        jsonArray.add(details);
        LOGGER.info("details=" + details.toString());

        jsonObject.add("extra", extra);
        jsonObject.add("details", jsonArray);*/

        TreeMap<String, String> treeMap = new TreeMap<String, String>();
        treeMap.put("tradeType", PayConfig.RM_TRADETYPE);
        treeMap.put("version", "1.0");
        treeMap.put("channel", PayConfig.RM_WECHAT_PAY);
        treeMap.put("mchId", PayConfig.RM_MCHID_TEST);
        treeMap.put("body", "下订单");
        treeMap.put("outTradeNo", order.getOutTradeNo());
        treeMap.put("amount", "0.01");
        treeMap.put("callbackUrl", PayConfig.RM_CALLBACK_URL);
        treeMap.put("notifyUrl", PayConfig.RM_NOTIFY_URL);
        treeMap.put("openId", PayConfig.RM_OPENID_TEST);
        treeMap.put("details", detailsArray.toString().replaceAll("\"", "").replaceAll(":", "=").replaceAll(",", "&"));

        try {
            String sign = genSign(treeMap);
            params.put("sign", sign);
//            jsonObject.addProperty("sign", sign);
            LOGGER.info(params.toString());

            HttpClient httpClient = new DefaultHttpClient();
            HttpPost method = new HttpPost(PayConfig.RM_PREPAYURL_TEST);
            method.setEntity(new StringEntity(params.toString(), Charset.forName("UTF-8")));

            HttpResponse response = httpClient.execute(method);
            int statusCode = response.getStatusLine().getStatusCode();
            LOGGER.info("statusCode=" + statusCode);

            String body = EntityUtils.toString(response.getEntity());
            LOGGER.info("RM prepay return: " + body);

//            JsonObject json = JSON.parseObject(body);
            JSONObject json = JSON.parseObject(body);
            LOGGER.info(json.get("tokenId").toString());
            return Message.success(json.get("tokenId").toString(), new Object[0]);
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
        return Message.error("预支付失败!", new Object[0]);
    }


    private String genSign(TreeMap map) throws UnsupportedEncodingException, IOException {
        StringBuffer buffer = new StringBuffer();
        Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry e = iter.next();
            buffer.append(e.getKey()).append("=").append(e.getValue()).append("&");
        }
        buffer.append("key=").append(PayConfig.RM_MD5KEY_TEST);
        LOGGER.info("buffer=" + buffer.toString());

//        byte[] byteArray = Digests.md5(new ByteArrayInputStream(buffer.toString().getBytes("UTF-8")));
//        String sign = Encodes.encodeHex(byteArray);

        String sign = MD5Util.MD5Encode(buffer.toString(), "utf-8");
        return sign.toUpperCase();
    }


}
